package com.company.libraryservice.service;

import com.company.libraryservice.mapper.BookMapper;
import com.company.libraryservice.mapper.BorrowRecordMapper;
import com.company.libraryservice.model.Book;
import com.company.libraryservice.model.BorrowRecord;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 图书业务服务
 *
 * @author RoyMa
 * @date 2025-08-12
 */
@Service
@RequiredArgsConstructor
public class BookService {
  private final BookMapper bookMapper;

  /** Redis模板，用于缓存图书列表数据 */
  private final RedisTemplate<String, Object> redisTemplate;

  private static final String BOOKS_CACHE = "books:all";

  private final BorrowRecordMapper recordMapper;

  /**
   * 获取图书列表，优先从缓存中获取
   *
   * @return 图书列表
   */
  @SuppressWarnings("unchecked")
  public List<Book> list() {
    // 先从缓存中获取
    Object cached = redisTemplate.opsForValue().get(BOOKS_CACHE);
    if (cached instanceof List<?>) {
      return (List<Book>) cached;
    }

    // 缓存未命中，从数据库查询
    List<Book> books = bookMapper.listBooks();

    // 将结果存入缓存，设置30秒过期时间
    redisTemplate.opsForValue().set(BOOKS_CACHE, books, 30, TimeUnit.SECONDS);

    return books;
  }

  /**
   * 添加图书
   *
   * @param b 图书对象
   */
  @Transactional(rollbackFor = Exception.class)
  public void add(Book b) {
    bookMapper.insert(b);
    // 新增图书后清除缓存，保证数据一致性
    redisTemplate.delete(BOOKS_CACHE);
  }

  /**
   * 借书操作
   *
   * @param id 图书ID
   * @return 是否借书成功
   */
  @Transactional(rollbackFor = Exception.class)
  public boolean borrow(Long id) {
    // 借书操作后清除缓存
    boolean result = bookMapper.borrow(id) > 0;
    if (result) {
      redisTemplate.delete(BOOKS_CACHE);
    }
    return result;
  }

  /**
   * 还书操作
   *
   * @param id 图书ID
   * @return 是否还书成功
   */
  @Transactional(rollbackFor = Exception.class)
  public boolean ret(Long id) {
    // 还书操作后清除缓存
    boolean result = bookMapper.ret(id) > 0;
    if (result) {
      redisTemplate.delete(BOOKS_CACHE);
    }
    return result;
  }

  public void borrowBook(Long id, String user) {
    if (!borrow(id)) {
      throw new RuntimeException("库存不足");
    }
  }

  public void returnBook(Long id, String user) {
    ret(id);
  }

  public List<BorrowRecord> listRecords() {
    return recordMapper.selectAll();
  }
}
